package com.ysjy.course.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.wkbb.common.base.BaseServiceImpl;
import com.wkbb.common.constants.ErrorCode;
import com.wkbb.common.constants.PromptMessage;
import com.wkbb.common.dto.ResultDTO;
import com.wkbb.common.dto.basic.StudentInfoDto;
import com.wkbb.common.handler.JsonUtil;
import com.wkbb.common.utils.DateUtil;
import com.wkbb.common.utils.RandomUtil;
import com.wkbb.sports.mapper.BasicMapper;
import com.ysjy.course.mapper.CourseMapper;
import com.ysjy.course.mapper.OrderMapper;
import com.ysjy.course.mapper.SignUpUserMapper;
import com.ysjy.course.mapper.TrusteeshipMapper;
import com.ysjy.course.model.*;
import com.ysjy.course.service.CourseClassService;
import com.ysjy.course.service.OrderService;
import com.ysjy.course.utils.WeChatPayUtil;
import com.ysjy.course.utils.XmlUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class OrderServiceImpl extends BaseServiceImpl<YsOrder> implements OrderService {

    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private CourseMapper courseMapper;
    @Autowired
    private TrusteeshipMapper trusteeshipMapper;
    @Autowired
    private SignUpUserMapper signUpUserMapper;
    @Autowired
    private BasicMapper basicMapper;
    @Autowired
    private CourseClassService courseClassService;

    @Autowired
    public void setMapper(OrderMapper mapper) {
        super.setMapper(mapper);
    }

    @Override
    public ResultDTO<YsOrder> putOrder(YsOrder data) throws Exception{
        //订单类型 1课程 2托管
        switch (data.getOrderType()){
            case 1:
                OrgCourse orgCourse = courseMapper.getOrgCourseByUniqueId(data.getGoodNumber(), data.getStudentId());
                if (orgCourse == null){
                    return ResultDTO.errorResult(PromptMessage.COURSE_IS_NULL);
                }
                orgCourse.initSignUpStatus();
                if (orgCourse.getSignUpStatus() == 3){
                    return ResultDTO.errorResult(PromptMessage.HAVE_SIGN_UP);
                }
                data.setTitle(orgCourse.getTitle());
                data.setAmount(orgCourse.getAmount());
                data.setLogo(orgCourse.getLogo());
                data.setOriginalAmount(orgCourse.getAmount());
                break;
            case 2:
                YsTrusteeship trusteeship = trusteeshipMapper.getTrusteeshipByUniqueId(data.getGoodNumber(), data.getStudentId());
                if (trusteeship == null){
                    return ResultDTO.errorResult(PromptMessage.TRUSTEESHIP_IS_NULL);
                }
                trusteeship.initSignUpStatus();
                if (trusteeship.getSignUpStatus() == 3){
                    return ResultDTO.errorResult(PromptMessage.HAVE_SIGN_UP);
                }
                data.setTitle(trusteeship.getTitle());
                data.setAmount(trusteeship.getAmount());
                data.setLogo(trusteeship.getLogo());
                data.setOriginalAmount(trusteeship.getAmount());
                break;
            case 3:
                YsCoursePackage coursePackage = courseMapper.getCoursePackageByUniqueId(data.getGoodNumber(), null);
                if (coursePackage == null){
                    return ResultDTO.errorResult(PromptMessage.TRUSTEESHIP_IS_NULL);
                }
                coursePackage.initSignUpStatus();
                if (coursePackage.getSignUpStatus() == 3){
                    return ResultDTO.errorResult(PromptMessage.HAVE_SIGN_UP);
                }
                data.setTitle(coursePackage.getTitle());
                data.setLogo(coursePackage.getLogo());
                data.setAmount(coursePackage.getAmount());
                data.setOriginalAmount(coursePackage.getAmount());
                break;
        }
        data.setPayType(1);
        data.setOrderNumber(DateUtil.getTodayyyyMMddHHmm() + RandomUtil.generateNumber(4));
        data.setUpdateTime(new Date());
//        log.info(JsonUtil.objectToJson(data));
        orderMapper.insert(data);
        return ResultDTO.successResult(data);
    }

    @Override
    public ResultDTO<Boolean> applyRefund(YsOrder data) {
        YsOrder order = orderMapper.getOrderByNumber(data.getOrderNumber());
        if (order == null){
            return ResultDTO.errorResult("不存在的订单");
        }
        if (!order.getUserId().equals(data.getUserId())){
            return ResultDTO.errorResult("不是当前用户的订单，不能进行该操作");
        }
        if (order.getPayStatus() != 1){
            return ResultDTO.errorResult("未支付订单，不能进行该操作");
        }
        if (order.getRefundStatus() != null){
            return ResultDTO.errorResult("已进行过退款申请操作，请勿重复申请");
        }
        if (data.getRefundAmount() > order.getAmount()){
            return ResultDTO.errorResult("退款金额不能大于订单金额");
        }
        YsOrder ysOrder = new YsOrder();
        ysOrder.setApplyRefundTime(new Date());
        ysOrder.setRefundWhy(data.getRefundWhy());
        ysOrder.setRefundExplain(data.getRefundExplain());
        ysOrder.setOrderNumber(data.getOrderNumber());
        ysOrder.setRefundAmount(data.getRefundAmount());
        ysOrder.setRefundStatus(0);
        orderMapper.update(ysOrder);
        return ResultDTO.successResult();
    }

    @Override
    public YsOrder getOrderByNumber(String orderNumber) {
        return orderMapper.getOrderByNumber(orderNumber);
    }

    @Override
    public boolean wxPayCallback(String notityXml) {
        System.out.println("进入微信支付回调参数》》》》》》》》》》》");
        System.out.println("xml>>>>>" + notityXml);
        WeChatPayResultLog chatPayResultLog = (WeChatPayResultLog) XmlUtils.stringToObject(notityXml,
                WeChatPayResultLog.class);
        if (null != chatPayResultLog && null != chatPayResultLog.getReturnCode()) {
            YsOrder order = orderMapper.getOrderByNumber(chatPayResultLog.getOutTradeNo());
            if (null != order) {
                int orderTotal = Integer.parseInt(chatPayResultLog.getTotalFee());
                if (orderTotal != order.getAmount()) {
                    log.error("订单价格不一致，订单号为：" + chatPayResultLog.getOutTradeNo() + "价格为：" + orderTotal);
                    return false;
                }
                order.setPayStatus(1);
                order.setPayType(1);
                order.setPayTime(new Date());
                order.setPayCode(chatPayResultLog.getTransactionId());
                order.setEnabled(true);
//                chatPayResultLog.getMchId()
                // 更新数据
                int updateOrderInfo = orderMapper.update(order);
                if (updateOrderInfo > 0){
                    if (order.getOrderType() == 3){
                        YsCoursePackage coursePackage = courseMapper.getCoursePackageByUniqueId(order.getGoodNumber(), null);
                        if (coursePackage != null){
                            if (coursePackage.getCourses() != null){
                                for(OrgCourse orgCourse:coursePackage.getCourses()){
                                    //添加到报名表
                                    SignUpUser signUpUser = new SignUpUser();
                                    signUpUser.setTitle(orgCourse.getTitle());
                                    signUpUser.setOrderNumber(order.getOrderNumber());
                                    signUpUser.setUserId(order.getUserId());
                                    signUpUser.setSignUpType(1);
                                    signUpUser.setStudentId(order.getStudentId());
                                    signUpUser.setStuName(order.getStuName());
                                    signUpUser.setStuClassName(order.getStuClassName());
                                    signUpUser.setStuGradeName(order.getStuGradeName());
                                    signUpUser.setAmount(order.getAmount());
                                    signUpUser.setType(1);
                                    signUpUser.setPayType(1);
                                    signUpUser.setGoodNumber(orgCourse.getUniqueId());
                                    signUpUser.setMobile(order.getMobile());
                                    signUpUser.setOrgId(order.getOrgId());
                                    signUpUser.setOrgName(order.getOrgName());
                                    signUpUser.setUpdateTime(new Date());
                                    signUpUserMapper.insert(signUpUser);
                                    //自动进班
                                    courseClassService.joinClassBySignUpUser(signUpUser);
                                }
                            }
                            if (coursePackage.getTrusteeships() != null){
                                for(YsTrusteeship ysTrusteeship:coursePackage.getTrusteeships()){
                                    //添加到报名表
                                    SignUpUser signUpUser = new SignUpUser();
                                    signUpUser.setTitle(ysTrusteeship.getTitle());
                                    signUpUser.setOrderNumber(order.getOrderNumber());
                                    signUpUser.setUserId(order.getUserId());
                                    signUpUser.setSignUpType(1);
                                    signUpUser.setStudentId(order.getStudentId());
                                    signUpUser.setStuName(order.getStuName());
                                    signUpUser.setStuClassName(order.getStuClassName());
                                    signUpUser.setStuGradeName(order.getStuGradeName());
                                    signUpUser.setAmount(order.getAmount());
                                    signUpUser.setType(1);
                                    signUpUser.setPayType(1);
                                    signUpUser.setGoodNumber(ysTrusteeship.getUniqueId());
                                    signUpUser.setMobile(order.getMobile());
                                    signUpUser.setOrgId(order.getOrgId());
                                    signUpUser.setOrgName(order.getOrgName());
                                    signUpUser.setUpdateTime(new Date());
                                    signUpUserMapper.insert(signUpUser);
                                    //自动进班
                                    courseClassService.joinClassBySignUpUser(signUpUser);
                                }
                            }
                        }
                    }else{
                        //添加到报名表
                        SignUpUser signUpUser = new SignUpUser();
                        signUpUser.setTitle(order.getTitle());
                        signUpUser.setOrderNumber(order.getOrderNumber());
                        signUpUser.setUserId(order.getUserId());
                        signUpUser.setSignUpType(order.getOrderType());
                        signUpUser.setStudentId(order.getStudentId());
                        signUpUser.setStuName(order.getStuName());
                        signUpUser.setStuClassName(order.getStuClassName());
                        signUpUser.setStuGradeName(order.getStuGradeName());
                        signUpUser.setAmount(order.getAmount());
                        signUpUser.setType(1);
                        signUpUser.setPayType(1);
                        signUpUser.setGoodNumber(order.getGoodNumber());
                        signUpUser.setMobile(order.getMobile());
                        signUpUser.setOrgId(order.getOrgId());
                        signUpUser.setOrgName(order.getOrgName());
                        signUpUser.setUpdateTime(new Date());
                        signUpUserMapper.insert(signUpUser);
                        //自动进班
                        courseClassService.joinClassBySignUpUser(signUpUser);
                    }
                }
                return updateOrderInfo > 0;
            }
        }
        return false;
    }

    @Override
    public ResultDTO<String> getPayInfo(YsOrder data) {
        YsOrder order = orderMapper.getOrderByNumber(data.getOrderNumber());
        if (order == null){
            return ResultDTO.errorResult("不存在的订单");
        }
//        if (!order.getUserId().equals(data.getUserId())){
//            return ResultDTO.errorResult("不是当前用户的订单，不能进行该操作");
//        }
        if (order.getPayStatus() == 1){
            return ResultDTO.errorResult("已支付订单，不能进行该操作");
        }
        YsOrder ysOrder = new YsOrder();
        ysOrder.setOrderNumber(data.getOrderNumber());
        ysOrder.setOpenId(data.getOpenId());
        orderMapper.update(ysOrder);
        //开始支付
        return WeChatPayUtil.pay(order);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultDTO<Boolean> auditRefund(YsOrder data) throws Exception {
        YsOrder order = orderMapper.getOrderByNumber(data.getOrderNumber());
        if (order == null){
            return ResultDTO.errorResult("不存在的订单");
        }
        if (order.getPayStatus() == 0){
            return ResultDTO.errorResult("未支付订单，不能进行该操作");
        }
        if (order.getRefundStatus() == 1){
            return ResultDTO.errorResult("已退款订单，不能进行该操作");
        }
        ResultDTO<Boolean> resultDTO;
        if (data.getRefundStatus() == 1){
            order.setRefundNumber("rf"+DateUtil.getTodayyyyMMddHHmm() + RandomUtil.generateNumber(4));
            order.setRefundTime(new Date());
            resultDTO = WeChatPayUtil.refund(order);
            if (resultDTO.isSuccess()){
                orderMapper.update(data);

                //报名表刷新
                SignUpUser signUpUser = signUpUserMapper.getByOrderNumber(data.getOrderNumber());
                if (signUpUser != null){
                    signUpUser.setRefundStatus(1);
                    signUpUser.setRefundTime(new Date());
                    signUpUserMapper.update(signUpUser);
                }
            }
        }else {
            orderMapper.update(data);
            resultDTO = new ResultDTO<>();
        }
        return resultDTO;
    }

    @Override
    public ResultDTO<MoneyStatistical> getOrderMoneyStatistical(Map<String, Object> params) {
        MoneyStatistical data = orderMapper.getOrderMoneyStatistical(params);
//        if (data != null) data.calc();
        return new ResultDTO<>(data);
    }

    @Override
    public void delOrder(String orderNumber) {
        orderMapper.delOrder(orderNumber);
    }

    @Override
    public PageInfo<OrgDto> getSchoolBusinessReportList(Map<String, Object> params, int pageNo, int pageSize) {
        Page<OrgDto> page = PageHelper.startPage(pageNo, pageSize,true);
        List<OrgDto> list = orderMapper.getSchoolBusinessReportList(params);
        for (OrgDto item : list){
            item.initSet();
        }
        PageInfo<OrgDto> pageInfo = new PageInfo<>(list);
        pageInfo.setTotal(page.getTotal());
        return pageInfo;
    }

    @Override
    public PageInfo<BusinessReport> getOrgCourseBusinessReportListByPage(Map<String, Object> params, Integer pageNo, Integer pageSize) {
        Page<BusinessReport> page = PageHelper.startPage(pageNo, pageSize,true);
        List<BusinessReport> list = orderMapper.getOrgCourseBusinessReportList(params);
        PageInfo<BusinessReport> pageInfo = new PageInfo<>(list);
        pageInfo.setTotal(page.getTotal());
        return pageInfo;
    }

    @Override
    public PageInfo<YsOrder> getOrderListByStudent(Map<String, Object> params, int pageNo, int pageSize) {
        Page<YsOrder> page = PageHelper.startPage(pageNo, pageSize,true);
        List<YsOrder> list = orderMapper.getOrderListByStudent(params);
        PageInfo<YsOrder> pageInfo = new PageInfo<>(list);
        pageInfo.setTotal(page.getTotal());
        return pageInfo;
    }

    @Override
    public ResultDTO<MoneyStatistical> getHomeStatistical(Map<String, Object> params) {
        MoneyStatistical data = orderMapper.getOrderMoneyStatistical(params);
        MoneyStatistical sign = signUpUserMapper.getSignUpStatistical(params);
        data.setSignUpNum(sign.getSignUpNum());
        data.setTodaySignUpNum(sign.getTodaySignUpNum());
        data.setWeekSignUpNum(sign.getWeekSignUpNum());
        return new ResultDTO<>(data);
    }

}
